package cn.iocoder.yudao.module.reading.dal.mysql.favorite;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.reading.dal.dataobject.favorite.UserFavoriteDO;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * 用户收藏 Mapper
 *
 * @author 芋道源码
 */
@Mapper
public interface UserFavoriteMapper extends BaseMapperX<UserFavoriteDO> {

    /**
     * 根据用户ID、收藏类型和目标ID查询收藏记录
     *
     * @param userId       用户ID
     * @param favoriteType 收藏类型
     * @param targetId     目标ID
     * @return 收藏记录
     */
    default UserFavoriteDO selectByUserIdAndTarget(Long userId, String favoriteType, Long targetId) {
        return selectOne(new LambdaQueryWrapperX<UserFavoriteDO>()
                .eq(UserFavoriteDO::getUserId, userId)
                .eq(UserFavoriteDO::getFavoriteType, favoriteType)
                .eq(UserFavoriteDO::getTargetId, targetId));
    }

    /**
     * 根据用户ID和收藏类型查询收藏列表
     *
     * @param userId       用户ID
     * @param favoriteType 收藏类型（可选）
     * @param limit        限制数量
     * @return 收藏列表
     */
    default List<UserFavoriteDO> selectByUserIdAndType(Long userId, String favoriteType, Integer limit) {
        return selectList(new LambdaQueryWrapperX<UserFavoriteDO>()
                .eq(UserFavoriteDO::getUserId, userId)
                .eqIfPresent(UserFavoriteDO::getFavoriteType, favoriteType)
                .orderByDesc(UserFavoriteDO::getCreateTime)
                .last(limit != null ? "LIMIT " + limit : ""));
    }

    /**
     * 根据用户ID查询收藏的目标ID列表
     *
     * @param userId       用户ID
     * @param favoriteType 收藏类型
     * @param targetIds    目标ID列表
     * @return 已收藏的目标ID列表
     */
    default List<Long> selectFavoriteTargetIds(Long userId, String favoriteType, List<Long> targetIds) {
        List<UserFavoriteDO> favorites = selectList(new LambdaQueryWrapperX<UserFavoriteDO>()
                .eq(UserFavoriteDO::getUserId, userId)
                .eq(UserFavoriteDO::getFavoriteType, favoriteType)
                .in(UserFavoriteDO::getTargetId, targetIds));
        
        return favorites.stream().map(UserFavoriteDO::getTargetId).toList();
    }

    /**
     * 统计用户收藏数量
     *
     * @param userId       用户ID
     * @param favoriteType 收藏类型（可选）
     * @return 收藏数量
     */
    default Long countByUserIdAndType(Long userId, String favoriteType) {
        return selectCount(new LambdaQueryWrapperX<UserFavoriteDO>()
                .eq(UserFavoriteDO::getUserId, userId)
                .eqIfPresent(UserFavoriteDO::getFavoriteType, favoriteType));
    }

    /**
     * 根据用户ID和收藏类型删除收藏
     *
     * @param userId       用户ID
     * @param favoriteType 收藏类型
     * @param targetId     目标ID
     * @return 删除数量
     */
    default int deleteByUserIdAndTarget(Long userId, String favoriteType, Long targetId) {
        return delete(new LambdaQueryWrapperX<UserFavoriteDO>()
                .eq(UserFavoriteDO::getUserId, userId)
                .eq(UserFavoriteDO::getFavoriteType, favoriteType)
                .eq(UserFavoriteDO::getTargetId, targetId));
    }

    /**
     * 清空用户某类型的收藏
     *
     * @param userId       用户ID
     * @param favoriteType 收藏类型
     * @return 删除数量
     */
    default int deleteByUserIdAndType(Long userId, String favoriteType) {
        return delete(new LambdaQueryWrapperX<UserFavoriteDO>()
                .eq(UserFavoriteDO::getUserId, userId)
                .eq(UserFavoriteDO::getFavoriteType, favoriteType));
    }

    /**
     * 分页查询用户收藏列表
     *
     * @param userId       用户ID
     * @param favoriteType 收藏类型（可选）
     * @param pageParam    分页参数
     * @return 分页结果
     */
    default PageResult<UserFavoriteDO> selectPageByUserIdAndType(Long userId, String favoriteType, PageParam pageParam) {
        return selectPage(pageParam, new LambdaQueryWrapperX<UserFavoriteDO>()
                .eq(UserFavoriteDO::getUserId, userId)
                .eqIfPresent(UserFavoriteDO::getFavoriteType, favoriteType)
                .orderByDesc(UserFavoriteDO::getCreateTime));
    }

}
